﻿using System;

namespace Cactussoft.Common.Logging
{
    internal sealed class TraceLogger : ILogger
    {
        public bool IsLogEnabled { get { return true; } }
        public bool IsDebugEnabled { get { return true; } }
        public bool IsTraceEnabled { get { return true; } }
        public bool IsInfoEnabled { get { return true; } }
        public bool IsWarnEnabled { get { return true; } }
        public bool IsErrorEnabled { get { return true; } }
        public bool IsFatalEnabled { get { return true; } }

        private static void Log(string type, string message)
        {
            try
            {
                System.Diagnostics.Trace.WriteLine(
                    "[{0}]:{1}".FormatWithInvariant(type, message));
            }
            catch (FormatException)
            {
                System.Diagnostics.Trace.WriteLine(
                    string.Concat("[FATAL]:FormatException: ", type, ",", message));
            }
            catch (ArgumentException)
            {
                System.Diagnostics.Trace.WriteLine(
                    string.Concat("[FATAL]:ArgumentException: ", type, ",", message));
            }
        }

        private static void Log(string type, string message, params object[] args)
        {
            try
            {
                var msg = message.FormatWithInvariant(args);

                System.Diagnostics.Trace.WriteLine(
                    "[{0}]:{1}".FormatWithInvariant(type, msg));
            }
            catch (FormatException)
            {
                System.Diagnostics.Trace.WriteLine(
                    string.Concat("[FATAL]:FormatException: ", type, ",", message));
            }
            catch (ArgumentException)
            {
                System.Diagnostics.Trace.WriteLine(
                    string.Concat("[FATAL]:ArgumentException: ", type, ",", message));
            }
        }

        private static void Log(string type, string message, Exception exception)
        {
            try
            {
                System.Diagnostics.Trace.WriteLine(
                    "[{0}]:{1}{2}{3}".FormatWithInvariant(
                        type, message, Environment.NewLine, exception.ToString()));
            }
            catch (FormatException)
            {
                System.Diagnostics.Trace.WriteLine(
                    string.Concat("FormatException: ", type, ",", message));
            }
            catch (ArgumentException)
            {
                System.Diagnostics.Trace.WriteLine(
                    string.Concat("ArgumentException: ", type, ",", message));
            }
        }

        private static void Log(string type, Exception exception)
        {
            try
            {
                System.Diagnostics.Trace.WriteLine(
                    "[{0}]:{1}{2}".FormatWithInvariant(
                        type, Environment.NewLine, exception.ToString()));
            }
            catch (FormatException)
            {
                System.Diagnostics.Trace.WriteLine(
                    string.Concat("[FATAL]:FormatException: ", type));
            }
            catch (ArgumentException)
            {
                System.Diagnostics.Trace.WriteLine(
                    string.Concat("[FATAL]:ArgumentException: ", type));
            }
        }

        #region ILogger Members

        public void Info(string message)
        {
            Log("INFO", message);
        }

        public void Info(string messageFormat, params object[] args)
        {
            Log("INFO", messageFormat, args);
        }

        public void Info(string message, Exception exception)
        {
            Log("INFO", message, exception);
        }

        public void Debug(string message)
        {
            Log("DEBUG", message);
        }

        public void Debug(string messageFormat, params object[] args)
        {
            Log("DEBUG", messageFormat, args);
        }

        public void Debug(string message, Exception exception)
        {
            Log("DEBUG", message, exception);
        }

        public void Trace(string message)
        {
            Log("TRACE", message);
        }

        public void Trace(string messageFormat, params object[] args)
        {
            Log("TRACE", messageFormat, args);
        }

        public void Trace(string message, Exception exception)
        {
            Log("TRACE", message, exception);
        }

        public void Warn(string message)
        {
            Log("WARN", message);
        }

        public void Warn(string messageFormat, params object[] args)
        {
            Log("WARN", messageFormat, args);
        }

        public void Warn(string message, Exception exception)
        {
            Log("WARN", message, exception);
        }

        public void Error(string message)
        {
            Log("ERROR", message);
        }

        public void Error(string messageFormat, params object[] args)
        {
            Log("ERROR", messageFormat, args);
        }

        public void Error(string message, Exception exception)
        {
            Log("ERROR", message, exception);
        }

        public void Error(Exception exception)
        {
            Log("ERROR", exception);
        }

        public void Fatal(string message)
        {
            Log("FATAL", message);
        }

        public void Fatal(string messageFormat, params object[] args)
        {
            Log("FATAL", messageFormat, args);
        }

        public void Fatal(string message, Exception exception)
        {
            Log("FATAL", message, exception);
        }

        public void Fatal(Exception exception)
        {
            Log("FATAL", exception);
        }

        #endregion
    }
}
